package formework.beans.support;

import formework.beans.config.DemoBeanDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class DemoBeanDefinitionReader {

    private List<String> registyBeanClasses = new ArrayList<String>();

    private Properties config = new Properties();

    private final String SCAN_PACKAGE = "scanPackage";

    public DemoBeanDefinitionReader(String ... location){
        for (int i = 0; i <location.length ; i++) {

            InputStream resource = this.getClass().getClassLoader().getResourceAsStream(location[i]);

            try {
                config.load(resource);
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    resource.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        doScanner(config.getProperty(SCAN_PACKAGE));
    }

    private void doScanner(String property) {

        URL resource = getClass().getClassLoader().getResource(property);

        File file = new File(resource.getFile());
        File[] files = file.listFiles();
        for (File fileF:files) {
            if(fileF.isDirectory()){
                doScanner(fileF.getName());
            }else {
                if(!fileF.getName().endsWith(".class")){
                    return;
                }
                registyBeanClasses.add(fileF.getName());
            }
        }

    }
    public Properties getConfig(){
        return this.config;
    }

    public List<DemoBeanDefinition> loadBeanDefinitions() {
        ArrayList<DemoBeanDefinition> result = new ArrayList<DemoBeanDefinition>();
        for(String className : registyBeanClasses){
            Class<?> clazz = null;
            try {
               clazz = Class.forName(className);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            if(clazz == null){
                continue;

            }
            //如果是一个接口，是不能实例化的
            //用它实现类来实例化
            if(clazz.isInterface()) { continue; }

            result.add(doCreateBeanDefinition(toLowerFirstCase(clazz.getSimpleName()),clazz.getName()));

            Class<?>[] interfaces = clazz.getInterfaces();
            for(Class<?> i : interfaces){

               result.add(doCreateBeanDefinition(toLowerFirstCase(i.getSimpleName()),i.getName()));
            }
        }
        return result;
    }

    //把每一个配信息解析成一个BeanDefinition
    private DemoBeanDefinition doCreateBeanDefinition(String factoryBeanName,String beanClassName){
        DemoBeanDefinition beanDefinition = new DemoBeanDefinition();
        beanDefinition.setBeanClassName(beanClassName);
        beanDefinition.setFactoryBeanName(factoryBeanName);
        return beanDefinition;
    }
    //如果类名本身是小写字母，确实会出问题
    //但是我要说明的是：这个方法是我自己用，private的
    //传值也是自己传，类也都遵循了驼峰命名法
    //默认传入的值，存在首字母小写的情况，也不可能出现非字母的情况

    //为了简化程序逻辑，就不做其他判断了，大家了解就OK
    //其实用写注释的时间都能够把逻辑写完了
    private String toLowerFirstCase(String simpleName) {
        char [] chars = simpleName.toCharArray();
        //之所以加，是因为大小写字母的ASCII码相差32，
        // 而且大写字母的ASCII码要小于小写字母的ASCII码
        //在Java中，对char做算学运算，实际上就是对ASCII码做算学运算
        chars[0] += 32;
        return String.valueOf(chars);
    }
}
